package com.example.administrator.bezier_nextpage;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Region.Op;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import com.nineoldandroids.animation.ValueAnimator;
import com.nineoldandroids.animation.ValueAnimator.AnimatorUpdateListener;


/**
 * Created by eyesee on 2017/3/29.
 */

public class BezierView extends View implements View.OnTouchListener {

    private Context mContext;
    private Paint mPaint;
    private Path mPath;
    private Path mPathNext;
    private ValueAnimator mValueAnimator;
    private int mWidth;
    private int mHeight;

    private static final int offset = 400;

    private float ax,ay,bx,by,cx,cy,dx,dy,ex,ey,fx,fy,gx,gy,hx,hy,ix,iy,jx,jy,kx,ky;
    private float cornerX, cornerY;
    private float outX , outY;

    public BezierView(Context context) {
        super(context);
        init(context);
    }

    public BezierView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);

    }

    private void init(Context context) {
        mContext = context;
        mPaint = new Paint();
        mPaint.setAntiAlias(true);
        mPaint.setStrokeWidth(1);
        mPath = new Path();
        mPathNext = new Path();
        setOnTouchListener(this);

        mValueAnimator = ValueAnimator.ofFloat(0, 50f);
        mValueAnimator.addUpdateListener(mAnimatorUpdateListener);
    }

    /**测量触点的宽高*/
    public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec,heightMeasureSpec);
        mWidth = getMeasuredWidth();
        mHeight = getMeasuredHeight();
        ax = cornerX = mWidth;
        ay = cornerY = mHeight;
    }

    /**开始绘制*/
    public void onDraw(Canvas canvas){
        /**绘制第二页正面,绿色*/
        calculatePoints();
        canvas.save();
        mPath.reset();
        mPath.moveTo(jx,jy);
        mPath.quadTo(hx,hy,kx,ky);
        mPath.lineTo(ax,ay);
        mPath.lineTo(bx,by);
        mPath.quadTo(ex,ey,cx,cy);
        mPath.lineTo(fx,fy);
        mPath.close();
        mPaint.setColor(Color.GREEN);
        canvas.drawPath(mPath,mPaint);
        canvas.restore();

        /**绘制正面
         * 画出path0,从j点到f点,再利用close把曲线封闭起来
         * */
        canvas.save();
        canvas.clipRect(canvas.getClipBounds());    //画出整个界面
        canvas.clipPath(mPath, Op.XOR);             //clip出path0的区域,然后根据XOR,取出path0没有圈住的区域
        canvas.drawColor(Color.RED);                //画红色
        canvas.restore();

        /**绘制背面
         * 利用difference操作,截取出页面背部分
         * */
        canvas.save();
        canvas.clipPath(mPath);
        mPathNext.reset();
        mPathNext.moveTo(cx,cy);
        mPathNext.quadTo(dx,dy,dx,dy);
        mPathNext.lineTo(ix,iy);
        mPathNext.quadTo(jx,jy,jx,jy);
        mPathNext.lineTo(fx,fy);
        mPathNext.close();
        canvas.clipPath(mPathNext, Op.DIFFERENCE);  //difference取出两段path中不同的地方
        canvas.drawColor(Color.YELLOW);
        canvas.restore();


    }

    /**触摸点的坐标*/
    @Override
    public boolean onTouch(View v, MotionEvent event) {
        switch (event.getAction()){
            case MotionEvent.ACTION_DOWN:
                float x = event.getX();     //触摸位置的X坐标
                float y = event.getY();     //触摸位置的Y坐标
                if (x< mWidth/2 && y< mHeight/2){
                    //second
                    cornerX = 0;
                    cornerY = 0;
                    outX = mWidth + offset;
                    outY = mHeight + offset;
                }else if (x< mWidth/2 && y> mHeight/2){
                    //third
                    cornerX = 0;
                    cornerY = mHeight;
                    outX = mWidth + offset;
                    outY = -offset;
                }else if (x> mWidth/2 && y< mHeight/2){
                    //first
                    cornerX = mWidth;
                    cornerY = 0;
                    outX=-offset;
                    outY = mHeight+ offset;
                }else if (x> mWidth/2 && y> mHeight/2){
                    //fourth
                    cornerX = mWidth;
                    cornerY = mHeight;
                    outX = -offset;
                    outY = -offset;
                }
                ax = x;
                ay = y;
                break;

            case MotionEvent.ACTION_MOVE:
                ax = event.getX();
                ay = event.getY();
                postInvalidate();
                break;
            case MotionEvent.ACTION_UP:
                mValueAnimator.setDuration(500).start();
                break;
        }
        return true;        //TODO  这里返回true
    }

    /**计算各点坐标的逻辑*/
    private void calculatePoints(){
        fx = cornerX;               //界面四个顶点之一,可根据手指落下时判断是哪个顶点
        fy = cornerY;

        gx = (ax + fx) / 2;         //g点是af的中点
        gy = (ay + fy) / 2;

        float gm = fy - gy;
        float mf = fx - gx;
        float em = gm * gm / mf;    //根据相似三角形算出em的长度

        ex = gx -em;                //算出e点
        ey = fy;

        float hm = mf * mf / gm;

        hx = fx;
        hy = gy - hm;               //算出h点

        cx = ex - (fx - ex)/2;      //再同理,三角形ehf跟三角形cjf是相似的,且根据cj是平分ag的,所以在边上的比例关系是2/3
        cy = fy;

        jx = fx;
        jy = hy - (fy - hy)/2;      //同上

        bx = (ax + ex) / 2;
        by = (ay + ey) / 2;         //b点是ae中点

        kx = (ax + hx) / 2;
        ky = (ay + hy) / 2;         //k点是ah的中点

        float px = (bx + cx) / 2;   //计算p点,是为了求d点,这一段曲线是对称的
        float py = (by + cy) / 2;   //p与e点连接起来,穿过的d点正好是曲线的中点

        dx = (px + ex) / 2;
        dy = (py + ey) / 2;         //d点是pe的中点

        px = (kx + jx) / 2;
        py = (ky + jy) / 2;         //同上

        ix = (px + hx) / 2;
        iy = (py + hy) / 2;
    }

    private AnimatorUpdateListener  mAnimatorUpdateListener = new AnimatorUpdateListener() {
        @Override
        public void onAnimationUpdate(ValueAnimator animation) {
            float currentValue = (float) animation.getAnimatedValue();
            float fraction = currentValue / 50f;
            ax += fraction*(outX - ax);
            ay += fraction*(outY - ay);
            postInvalidate();
        }
    };
}
